{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "<h1> Deploying and predicting with model </h1>\n",
    "\n",
    "<h2>Learning Objectives</h2>\n",
    "<ol>\n",
    "    <li>Create the model using ai-platform CLI commands</li>\n",
    "<li>Deploy the ML model to production</li>\n",
    "    <li>Perform predictions with the model</li>\n",
    "</ol>\n",
    "\n",
    "__TODO__: Complete the lab notebook #TODO sections. You can refer to the [solutions/](../solutions/6_deploy.ipynb) notebook for reference. \n"
   ]
  },
  {

"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"# Ensure the right version of Tensorflow is installed.\n",
"!pip freeze | grep tensorflow==2.1"
]
},

  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# change these to try this notebook out\n",
    "BUCKET = 'cloud-training-demos-ml'\n",
    "PROJECT = 'cloud-training-demos'\n",
    "REGION = 'us-central1'"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "import os\n",
    "os.environ['BUCKET'] = BUCKET\n",
    "os.environ['PROJECT'] = PROJECT\n",
    "os.environ['REGION'] = REGION\n",
    "os.environ['TFVERSION'] = '2.1'  "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "%%bash\n",
    "if ! gcloud storage ls | grep -q gs://${BUCKET}/babyweight/trained_model; then\n",
    "  gcloud storage buckets create --location=${REGION} gs://${BUCKET}\n",
    "  # copy canonical model if you didn't do previous notebook\n",
    "  gcloud storage cp --recursive gs://cloud-training-demos/babyweight/trained_model gs://${BUCKET}/babyweight\n",
    "fi"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "<h2> Deploy trained model </h2>\n",
    "<p>\n",
    "Deploying the trained model to act as a REST web service is a simple gcloud call."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "%%bash\n",
    "gcloud storage ls gs://${BUCKET}/babyweight/trained_model/export/exporter/"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "%%bash\n",
    "MODEL_NAME=\"babyweight\"\n",
    "MODEL_VERSION=\"ml_on_gcp\"\n",
    "MODEL_LOCATION=$(gcloud storage ls gs://${BUCKET}/babyweight/trained_model/export/exporter/ | tail -1)\n",
    "echo \"Deleting and deploying $MODEL_NAME $MODEL_VERSION from $MODEL_LOCATION ... this will take a few minutes\"\n",
    "\n",
    "# Optional: Delete the version of the model if it already exists:\n",
    "#gcloud ai-platform versions delete ${MODEL_VERSION} --model ${MODEL_NAME}\n",
    "#gcloud ai-platform models delete ${MODEL_NAME}\n",
    "\n",
    "# TODO: Create the model \n",
    "gcloud ai-platform models create \n",
    "\n",
    "# TODO: Create the model version \n",
    "gcloud ai-platform versions create"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "<h2> Use model to predict (online prediction) </h2>\n",
    "<p>\n",
    "Send a JSON request to the endpoint of the service to make it predict a baby's weight. The order of the responses are the order of the instances."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from oauth2client.client import GoogleCredentials\n",
    "import requests\n",
    "import json\n",
    "\n",
    "MODEL_NAME = 'babyweight'\n",
    "MODEL_VERSION = 'ml_on_gcp'\n",
    "\n",
    "token = GoogleCredentials.get_application_default().get_access_token().access_token\n",
    "api = 'https://ml.googleapis.com/v1/projects/{}/models/{}/versions/{}:predict' \\\n",
    "         .format(PROJECT, MODEL_NAME, MODEL_VERSION)\n",
    "headers = {'Authorization': 'Bearer ' + token }\n",
    "data = {\n",
    "  'instances': [\n",
    "    {\n",
    "      'key': 'b1',\n",
    "      'is_male': 'True',\n",
    "      'mother_age': 26.0,\n",
    "      'plurality': 'Single(1)',\n",
    "      'gestation_weeks': 39\n",
    "    },\n",
    "    {\n",
    "      'key': 'g1',\n",
    "      'is_male': 'False',\n",
    "      'mother_age': 29.0,\n",
    "      'plurality': 'Single(1)',\n",
    "      'gestation_weeks': 38\n",
    "    },\n",
    "    {\n",
    "      'key': 'b2',\n",
    "      'is_male': 'True',\n",
    "      'mother_age': 26.0,\n",
    "      'plurality': 'Triplets(3)',\n",
    "      'gestation_weeks': 39\n",
    "    },\n",
    "    {\n",
    "      'key': 'u1',\n",
    "      'is_male': 'Unknown',\n",
    "      'mother_age': 29.0,\n",
    "      'plurality': 'Multiple(2+)',\n",
    "      'gestation_weeks': 38\n",
    "    },\n",
    "  ]\n",
    "}\n",
    "response = requests.post(api, json=data, headers=headers)\n",
    "print(response.content)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "The predictions for the four instances were: 7.66, 7.22, 6.32 and 6.19 pounds respectively when I ran it (your results might be different)."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "<h2> Use model to predict (batch prediction) </h2>\n",
    "<p>\n",
    "Batch prediction is commonly used when you thousands to millions of predictions.\n",
    "Create a file with one instance per line and submit using gcloud."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "%%writefile inputs.json\n",
    "{\"key\": \"b1\", \"is_male\": \"True\", \"mother_age\": 26.0, \"plurality\": \"Single(1)\", \"gestation_weeks\": 39}\n",
    "{\"key\": \"g1\", \"is_male\": \"False\", \"mother_age\": 26.0, \"plurality\": \"Single(1)\", \"gestation_weeks\": 39}"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "%%bash\n",
    "INPUT=gs://${BUCKET}/babyweight/batchpred/inputs.json\n",
    "OUTPUT=gs://${BUCKET}/babyweight/batchpred/outputs\n",
    "gcloud storage cp inputs.json $INPUT\n",
    "gcloud storage rm --recursive --continue-on-error $OUTPUT \n",
    "\n",
    "gcloud ai-platform jobs submit prediction babypred_$(date -u +%y%m%d_%H%M%S) \\\n",
    "  --data-format=TEXT --region ${REGION} \\\n",
    "  --input-paths=$INPUT \\\n",
    "  --output-path=$OUTPUT \\\n",
    "  --model=babyweight --version=ml_on_gcp"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Copyright 2020 Google Inc. Licensed under the Apache License, Version 2.0 (the \"License\"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.5.3"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 4
}
